﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using System.ComponentModel;

namespace mBlogPat
{
	public partial class MainPage : UserControl
    {

        #region 供JavaScript与SilverLight使用的结构和类

        public struct TweetTimeInfo //微薄的时间数据
        {
            public Int64 SpreadTime { get; set; } //发送时间

            public Int64 NowTime { get; set; } //当前服务器时间
        }

        public class TweetInfo
        {            
            public String Text { get; set; }

            //public Int32 RespreadCount { get; set; }
            
            //public String From { get; set; }

            public Int64 TweetId { get; set; }

            public String Image { get; set; }

            public String UserName { get; set; }

            public String NickName { get; set; }

            public TweetTimeInfo TweetTime { get; set; }

            public Int32 Type { get; set; }

            public String HeadImage { get; set; }

            public Int32 IsVIP { get; set; }

            //public String Location { get; set; }

            //SourceInfo 当Type等于2时，以下内容有效
            
            public String SourceText { get; set; }

            public Int64 SourceTweetId { get; set; }

            public String SourceImage { get; set; }

            public String SourceUserName { get; set; }

            public String SourceNickName { get; set; }
                        
            public TweetInfo ListItemTag { get; set; } //为空间获得微薄信息提供的接口
            
            public TweetInfo()
            {
                ListItemTag = this;
            }
        }

        public class UserBlogInfo //用户信息
        {
            public String UserName{get;set;}

            public String NickName{get;set;}

            public String HeadImage{get;set;}

            public String Location{get;set;}

            public Int64 FansNumber{get;set;}

            public Int32 ListenNumber{get;set;}
        }
                
        #endregion



        #region 供JavaScript调用的回调函数

        //将微薄信息加入指定时间线列表
        [ScriptableMember]
        public void jsTimeLineListAdd(String Text, Int64 TweetId, String Image, String UserName,
                                    String NickName, Int64 SpreadTime, Int64 NowTime, Int32 Type,
                                    String HeadImage,String SourceText, Int64 SourceTweetId,
                                    String SourceImage,String SourceUserName,
                                    String SourceNickName,Int32 IsVIP, Int32 TimeLineType)
        {

            TweetInfo tweetInfo = new TweetInfo();
            tweetInfo.Text = Text;
            //tweetInfo.RespreadCount = RespreadCount;
            //tweetInfo.From = From;
            tweetInfo.TweetId = TweetId;
            tweetInfo.Image = Image;
            tweetInfo.UserName = UserName;
            tweetInfo.NickName = NickName;
            
            TweetTimeInfo tweetTime = new TweetTimeInfo();
            tweetTime.NowTime = NowTime;
            tweetTime.SpreadTime = SpreadTime;
            tweetInfo.TweetTime = tweetTime;

            tweetInfo.Type = Type;
            tweetInfo.HeadImage = HeadImage;
            tweetInfo.IsVIP = IsVIP;
            //tweetInfo.Location = Location;

            tweetInfo.SourceText = SourceText;
            tweetInfo.SourceTweetId = SourceTweetId;
            tweetInfo.SourceImage = SourceImage;
            tweetInfo.SourceUserName = SourceUserName;
            tweetInfo.SourceNickName = SourceNickName;
            
            ObservableCollection<TweetInfo> TimeLine = GetTimeLineListByTimeLineType(TimeLineType);

            TimeLine.Add(tweetInfo);
            
        }

        //获取个人信息完成的回调函数
        [ScriptableMember]
        public void jsGetMyBlogInfoFinished(String UserName, String NickName, String HeadImage,
                                            String Location, Int64 FansNumber, Int32 ListenNumber)
        {
            MyInfo.UserName = UserName;
            MyInfo.NickName = NickName;
            MyInfo.HeadImage = HeadImage;
            MyInfo.Location = Location;
            MyInfo.FansNumber = FansNumber;
            MyInfo.ListenNumber = ListenNumber;
        }

        //用于主页时间线的实时更新,同时对更新内容进行提示检查，每5秒执行一次
        [ScriptableMember]
        public void jsUpdateHomeTimeLine(String Text, Int64 TweetId, String Image, String UserName,
                                    String NickName, Int64 SpreadTime,Int64 NowTime, Int32 Type,
                                    String HeadImage, String SourceText,
                                    Int64 SourceTweetId, String SourceImage, String SourceUserName,
                                    String SourceNickName,Int32 IsVIP,Int32 InsertIndex,Int32 HasNext)
        {
            TweetInfo tweetInfo = new TweetInfo();
            tweetInfo.Text = Text;
            //tweetInfo.RespreadCount = RespreadCount;
            //tweetInfo.From = From;
            tweetInfo.TweetId = TweetId;
            tweetInfo.Image = Image;
            tweetInfo.UserName = UserName;
            tweetInfo.NickName = NickName;

            TweetTimeInfo tweetTime = new TweetTimeInfo();
            tweetTime.NowTime = NowTime;
            tweetTime.SpreadTime = SpreadTime;
            tweetInfo.TweetTime = tweetTime;

            tweetInfo.Type = Type;
            tweetInfo.HeadImage = HeadImage;
            tweetInfo.IsVIP = IsVIP;
            //tweetInfo.Location = Location;

            tweetInfo.SourceText = SourceText;
            tweetInfo.SourceTweetId = SourceTweetId;
            tweetInfo.SourceImage = SourceImage;
            tweetInfo.SourceUserName = SourceUserName;
            tweetInfo.SourceNickName = SourceNickName;
            
            HomeTimeLineListSource.Insert(InsertIndex, tweetInfo);
            CheckIsTrailedBlog(tweetInfo);

            if (HasNext == 0) //如果还有微薄可以更新，就继续调用JS函数，否则进入下一计时周期
            {
                HtmlPage.Window.Invoke("updateHomeTimeLine", HomeTimeLineListSource[0].TweetTime.SpreadTime);
            }
            else
            {
                jsContinueUpdateHomeTimeLineTick();
            }
        }

        //当一次主页时间线更新结束后被调用，启动计时器，准备下一次更新
        [ScriptableMember]
        public void jsContinueUpdateHomeTimeLineTick()
        {
            HomeTimeLineUpdateTimer.Start();
        }

        //发送微薄成功时调用
        [ScriptableMember]
        public void jsSendTweetSuccess(Int64 TweetId, Int64 SpreadTime)
        {
            MessageBox.Show("微薄发送成功，id:" + TweetId.ToString());
        }

        //删除微薄成功时调用
        [ScriptableMember]
        public void jsDeleteTweetSuccess(Int64 TweetId)
        {
            foreach (TweetInfo Tweet in HomeTimeLineListSource)
            {
                if (Tweet.TweetId == TweetId)
                {
                    HomeTimeLineListSource.Remove(Tweet);
                    break;
                }
            }
            MessageBox.Show("微薄删除成功，id:" + TweetId.ToString());
        }

        [ScriptableMember]
        public void jsRespreadTweetSuccess(Int64 TweetId, Int64 Time)
        {
            MessageBox.Show("转播成功");
        }

        [ScriptableMember]
        public void jsReplyTweetSuccess(Int64 TweetId, Int64 Time)
        {
            MessageBox.Show("回复成功");
        }

        //添加追踪微薄时调用
        [ScriptableMember]
        public void jsAddTrailedBlog(String UserName, String NickName, String HeadImage,
                                     String Location, Int64 FansNumber, Int32 ListenNumber)
        {
            UserBlogInfo userInfo = new UserBlogInfo();
            userInfo.UserName = UserName;
            userInfo.NickName = NickName;
            userInfo.HeadImage = HeadImage;
            userInfo.Location = Location;
            userInfo.FansNumber = FansNumber;
            userInfo.ListenNumber = ListenNumber;

            TrailedBlogListSource.Add(userInfo);
        }
        
        #endregion



        #region 从SilverLight调用JavaScript的函数
        
        //获取自己的用户信息
        private void GetMyBlogInfo()
        {
            HtmlPage.Window.Invoke("getMyBlogInformation");
        }

        //初始化指定时间线列表，列表之前的内容将在清空后从新载入
        private void InitTimeLineList(Int32 TimeLineType,String TargetUserName = null)
        {
            TimeLineListClear(TimeLineType);

            switch (TimeLineType)
            {
                case 0:
                    HtmlPage.Window.Invoke("showPublicTimeLine", 0, 15);
                    break;
                case 1:
                    HtmlPage.Window.Invoke("showHomeTimeLine",0,0,15);
                    break;
                case 2:
                    HtmlPage.Window.Invoke("showUserTimeLine",0,0,15,0,TargetUserName);
                    break;
            }
        }

        //对指定时间线列表追加微薄
        private void AppendTimeLineList(Int32 TimeLineType,Int32 PageFlag,Int64 PageTime, Int32 RequireNumber,Int64 LastId = 0,String TargetUserName = null)
        {
            switch (TimeLineType)
            {
                case 0:
                    HtmlPage.Window.Invoke("showPublicTimeLine", PageTime, RequireNumber);
                    break;
                case 1:
                    HtmlPage.Window.Invoke("showHomeTimeLine", PageFlag, PageTime, RequireNumber);
                    break;
                case 2:
                    HtmlPage.Window.Invoke("showUserTimeLine",PageFlag, PageTime, RequireNumber, LastId, TargetUserName);
                    break;
            }
        }

        //清楚指定时间线列表
        private void TimeLineListClear(Int32 TimeLineType)
        {
            switch (TimeLineType)
            {
                case 0:
                    PublicTimeLineListSource.Clear();
                    break;
                case 1:
                    HomeTimeLineListSource.Clear();
                    break;
                case 2:
                    UserTimeLineListSource.Clear();
                    break;
            }

        }

        //根据时间线类型返回对时间线源的引用
        private ObservableCollection<TweetInfo> GetTimeLineListByTimeLineType(Int32 TimeLineType)
        {
            switch (TimeLineType)
            {
                case 0:
                    return PublicTimeLineListSource;
                case 1:
                    return HomeTimeLineListSource;
                case 2:
                    return UserTimeLineListSource;
            }

            return null;
        }
        
        //将指定时间线源作为TimeLineList的源
        private void ChangeTimeLineType(Int32 TimeLineType)
        {
            TimeLineList.ItemsSource = null;
            switch (TimeLineType)
            {
                case 0:
                    TimeLineList.ItemsSource = PublicTimeLineListSource;
                    break;
                case 1:
                    TimeLineList.ItemsSource = HomeTimeLineListSource;
                    break;
                case 2:
                    TimeLineList.ItemsSource = UserTimeLineListSource;
                    break;
            }

            CurrentTimeLineType = TimeLineType;
        }

        //检查是否是跟踪的微薄，如果是就进行提示
        private void CheckIsTrailedBlog(TweetInfo tweetInfo)
        {

        }

        //添加要追踪的微薄
        private void AddTrailedBlog(String UserName)
        {
            HtmlPage.Window.Invoke("addTrailedBlog", UserName);
        }
                
        //发送一条微薄
        private void SendTweet(String Text)
        {
            HtmlPage.Window.Invoke("sendTweet", Text);
        }

        //发送带图片的微薄
        private void SendTweetWithPic(String Text, String ClientIP, String Image)
        {
            HtmlPage.Window.Invoke("sendTweetWithPic", Text, ClientIP, Image);
        }

        //删除一条微薄
        private void DeleteTweet(Int64 TweetId)
        {
            HtmlPage.Window.Invoke("deleteTweet", TweetId);
        }

        //回复一条微薄
        private void ReplyTweet(String Text, Int64 TargetTweetId)
        {
            HtmlPage.Window.Invoke("replyTweet", Text, TargetTweetId);
        }

        //转播一条微薄
        private void RespreadTweet(String Text, Int64 SourceTweetId)
        {
            HtmlPage.Window.Invoke("respreadTweet", Text, SourceTweetId);
        }

        //收藏一条微薄
        private void SaveTweet(Int64 TweetId)
        {
            HtmlPage.Window.Invoke("saveTweet", TweetId);
        }

        //取消收藏指定微薄
        private void UnsaveTweet(Int64 TweetId)
        {
            HtmlPage.Window.Invoke("unsaveTweet", TweetId);
        }

        //发送一条私信
        private void SendPrivateTweet(String Text, String TargetUserName)
        {
            HtmlPage.Window.Invoke("sendPrivateTweet", Text, TargetUserName);
        }

        //删除一条私信
        private void DeletePrivateTweet(Int64 TweetId)
        {
            HtmlPage.Window.Invoke("deletePrivateTweet", TweetId);
        }

        //收听一位用户
        private void AddFriend(String UserName)
        {
            HtmlPage.Window.Invoke("addFriend", UserName);
        }

        //取消收听用户
        private void DelFriend(String UserName)
        {
            HtmlPage.Window.Invoke("delFriend", UserName);
        }

        //设置挂件显示区域大小
        private void SetWidgetSize(Int32 Width, Int32 Height)
        {
            HtmlPage.Window.Invoke("setWidgetSize", Width, Height);
        }

        //拖动微薄
        private void StartDragWidget()
        {
            HtmlPage.Window.Invoke("startDragWidget");
        }

        private void OpenURL(String URL)
        {
            HtmlPage.Window.Invoke("openURL", URL);
        }

        #endregion


        #region 主要事件过程与处理

        //广播大厅时间线
        ObservableCollection<TweetInfo> PublicTimeLineListSource = new ObservableCollection<TweetInfo>();
        //主页时间线
        ObservableCollection<TweetInfo> HomeTimeLineListSource = new ObservableCollection<TweetInfo>();
        //指定用户的时间线
        ObservableCollection<TweetInfo> UserTimeLineListSource = new ObservableCollection<TweetInfo>();

        //要追踪的用户列表
        ObservableCollection<UserBlogInfo> TrailedBlogListSource = new ObservableCollection<UserBlogInfo>();

        //用于储存自己的信息
        UserBlogInfo MyInfo = new UserBlogInfo();

        //用于主页时间线动态更新的计时器
        DispatcherTimer HomeTimeLineUpdateTimer = new DispatcherTimer();

        //当前所显示的时间线类型，默认为HomeTimeLine
        Int32 CurrentTimeLineType = 1;

        public MainPage()
        {
            // 为初始化变量所必需
            InitializeComponent();

            this.Loaded += new RoutedEventHandler(Page_Loaded);
            TimeLineList.ItemsSource = HomeTimeLineListSource;
            
            HomeTimeLineUpdateTimer.Interval = TimeSpan.FromSeconds(5);
            HomeTimeLineUpdateTimer.Tick += new EventHandler(HomeTimeLineUpdateTimer_Tick);
        }

		void Page_Loaded(object sender,RoutedEventArgs e)
		{
			HtmlPage.RegisterScriptableObject("myMainPage",this);
            
            SetWidgetSize(300, 440); //修改挂件到合适大小

            GetMyBlogInfo(); //获取自己的信息
            
            InitTimeLineList(1); //初始化主页时间线，显示最新15条微薄
            HomeTimeLineUpdateTimer.Start(); //更新计时器开始计时

        }

        #endregion



        #region 控件事件与控件内部过程

        private Grid CurrentSelectedGrid = null;//当前选定的回复框，主要用于动画操作

        

        //更新计时器的Tick事件
        private void HomeTimeLineUpdateTimer_Tick(object sender, EventArgs e)
        {
            HomeTimeLineUpdateTimer.Stop();

            HtmlPage.Window.Invoke("updateHomeTimeLine", HomeTimeLineListSource[0].TweetTime.SpreadTime);
        }
       
        //当用户头像加载失败时调用，用于显示一个替代头像
        private void HeadImage_ImageFailed(object sender, System.Windows.ExceptionRoutedEventArgs e)
        {
            //MessageBox.Show("Got an error!");
            Image SenderImage = sender as Image;
            SenderImage.ImageFailed -= new EventHandler<ExceptionRoutedEventArgs>(HeadImage_ImageFailed); //防止重入
            SenderImage.Source = new BitmapImage(new Uri("http://mat1.gtimg.com/www/mb/images/head_40.jpg"));

        }

        //当TimeLineList的滚动条到最下端时，及时添加微薄
        private void ScrallBar_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
        {
            double Max = (sender as ScrollBar).Maximum;
            if (e.NewValue == Max)
            {
                switch (CurrentTimeLineType)
                {
                    case 0:
                        {
                            Int64 pageTime = PublicTimeLineListSource[PublicTimeLineListSource.Count - 1].TweetTime.SpreadTime;
                            AppendTimeLineList(0, 1, pageTime, 5);
                            break;
                        }
                    case 1:
                        {
                            Int64 pageTime = HomeTimeLineListSource[HomeTimeLineListSource.Count - 1].TweetTime.SpreadTime;
                            AppendTimeLineList(1, 1, pageTime, 5);
                            break;
                        }
                    case 2:
                        {
                            TweetInfo info = UserTimeLineListSource[UserTimeLineListSource.Count - 1];
                            Int64 pageTime = info.TweetTime.SpreadTime;
                            Int64 lastId = info.TweetId;
                            String userName = info.UserName;
                            AppendTimeLineList(2, 1, pageTime, 5, lastId, userName);
                            break;
                        }

                }
            }
        }

        //单击某一条微薄的转发按钮
        private void ListItemClick_Respread(object sender, System.Windows.RoutedEventArgs e)
        {
            Grid RGrid = (sender as Button).Tag as Grid;
            Button btnSend = RGrid.Children[1] as Button;

            if (CurrentSelectedGrid == RGrid && btnSend.Content.ToString() == "转播")
            {
                if (RGrid.Visibility == System.Windows.Visibility.Visible)
                {
                    RGridCloseWithAnimation(RGrid);
                    //RGrid.Visibility = System.Windows.Visibility.Collapsed;
                }
                else
                {
                    RGridOpenWithAnimation(RGrid);
                    //RGrid.Visibility = System.Windows.Visibility.Visible;
                }
                return;
            }

            if (CurrentSelectedGrid != RGrid && CurrentSelectedGrid != null)
            {
                RGridCloseWithAnimation(CurrentSelectedGrid);
            }

            CurrentSelectedGrid = RGrid;
            btnSend.Content = "转播";

            RGridOpenWithAnimation(RGrid);
        }

        //单击某一条微薄的回复按钮
        private void ListItemClick_Reply(object sender, System.Windows.RoutedEventArgs e)
        {
            Grid RGrid = (sender as Button).Tag as Grid;
            Button btnSend = RGrid.Children[1] as Button;

            if (CurrentSelectedGrid == RGrid && btnSend.Content.ToString() == "回复")
            {
                if (RGrid.Visibility == System.Windows.Visibility.Visible)
                {
                    RGridCloseWithAnimation(RGrid);
                }
                else
                {
                    RGridOpenWithAnimation(RGrid);
                }
                return;
            }

            if (CurrentSelectedGrid != RGrid && CurrentSelectedGrid != null)
            {
                RGridCloseWithAnimation(CurrentSelectedGrid);
            }

            CurrentSelectedGrid = RGrid;
            btnSend.Content = "回复";

            RGridOpenWithAnimation(RGrid);
        }

        //单击某一条微薄的收藏微薄
        private void ListItemClick_Save(object sender, System.Windows.RoutedEventArgs e)
        {
            TweetInfo info = (sender as Button).Tag as TweetInfo;
            SaveTweet(info.TweetId);
        }

        //回复或转发
        private void ListItemClick_Send(object sender, System.Windows.RoutedEventArgs e)
        {
            Grid RGrid = (sender as Button).Tag as Grid;
            TextBox ReplyBox = RGrid.Children[0] as TextBox;
            Button btnSend = RGrid.Children[1] as Button;
            
            TweetInfo info = RGrid.Tag as TweetInfo;

            if (btnSend.Content.ToString() == "转播")
            {
                Int64 TweetId = (info.SourceTweetId == 0) ? info.TweetId : info.SourceTweetId;
                RespreadTweet(ReplyBox.Text, TweetId);
            }
            else
            {
                ReplyTweet(ReplyBox.Text, info.TweetId);
            }

            ReplyBox.Text = "";
            RGridCloseWithAnimation(RGrid);

        }

        //单击用户名时切换到该用户的时间线列表
        private void UserName_Click(object sender, System.Windows.RoutedEventArgs e)
        {            
            TweetInfo info = (sender as HyperlinkButton).Tag as TweetInfo;
            
            ChangeTimeLineType(2);

            //MessageBox.Show(info.UserName);

            InitTimeLineList(2, info.UserName);
        }

        //当鼠标移到“查看图片”上时，显示一幅缩略图
        private void ShowImage_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            TweetInfo info = (sender as HyperlinkButton).Tag as TweetInfo;

            Point p = e.GetPosition(FlowtImagePopup);

            BitmapImage ImgBitmap = new BitmapImage(new Uri(info.Image + "/160"));
            ImgLoadProgressBar.Value = 0;
            ImgBitmap.DownloadProgress += (object s, DownloadProgressEventArgs ee) =>
            {
                ImgLoadProgressBar.Value = ee.Progress;
            };
            FlowtImage.Source = ImgBitmap;
            
            double newX = p.X;
            double newY = (p.Y > 250) ? (p.Y - 130) : (p.Y + 15);
            double Yfrom = (p.Y > 250) ? (p.Y - 145) : (p.Y + 30);
            
            FlowtImageOpenWithAnimation(newX, newY, Yfrom);
        }

        //鼠标离开“查看图片”时，关闭缩略图
        private void ShowImage_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            FlowtImageCloseWithAnimation();
        }

        //当鼠标移到“查看图片”上时，显示一幅缩略图（转播的图片）
        private void ShowSrcImage_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
        {
            TweetInfo info = (sender as HyperlinkButton).Tag as TweetInfo;

            Point p = e.GetPosition(FlowtImagePopup);

            BitmapImage ImgBitmap = new BitmapImage(new Uri(info.SourceImage + "/160"));
            ImgLoadProgressBar.Value = 0;
            ImgBitmap.DownloadProgress += (object s, DownloadProgressEventArgs ee) =>
            {
                ImgLoadProgressBar.Value = ee.Progress;
            };
            FlowtImage.Source = ImgBitmap;

            double newX = p.X;
            double newY = (p.Y > 250) ? (p.Y - 130) : (p.Y + 15);
            double Yfrom = (p.Y > 250) ? (p.Y - 145) : (p.Y + 30);

            FlowtImageOpenWithAnimation(newX, newY, Yfrom);
            
        }

        //单击“查看图片”时，调用内置浏览器显示大图
        private void ShowImage_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            TweetInfo info = (sender as HyperlinkButton).Tag as TweetInfo;
            OpenURL(info.Image + "/460");
        }

        //单击“查看图片”时，调用内置浏览器显示大图（转播的图片）
        private void ShowSrcImage_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            TweetInfo info = (sender as HyperlinkButton).Tag as TweetInfo;
            OpenURL(info.SourceImage + "/460");
        }

        #region 动画

        //浮动图片框显示动画
        private void FlowtImageOpenWithAnimation(double X,double Y,double Yfrom)
        {
            FlowtImagePopup.IsOpen = true;

            Storyboard OpenAnimations = new Storyboard();
            OpenAnimations.BeginTime = TimeSpan.FromSeconds(0.4); //延迟显示
            Duration duration = new Duration(TimeSpan.FromSeconds(0.3));

            DoubleAnimation OpacityAnimation = new DoubleAnimation();
            OpacityAnimation.Duration = duration;
            OpacityAnimation.To = 1;
            Storyboard.SetTarget(OpacityAnimation, FlowtImageBox);
            Storyboard.SetTargetProperty(OpacityAnimation, new PropertyPath("Opacity"));
            OpenAnimations.Children.Add(OpacityAnimation);

            DoubleAnimation Xanimation = new DoubleAnimation();
            Xanimation.Duration = duration;
            Xanimation.To = X;
            Storyboard.SetTarget(Xanimation, FlowtImagePopup);
            Storyboard.SetTargetProperty(Xanimation,new PropertyPath("HorizontalOffset"));
            OpenAnimations.Children.Add(Xanimation);

            DoubleAnimation Yanimation = new DoubleAnimation();
            Yanimation.Duration = duration;
            Yanimation.From = Yfrom;
            Yanimation.To = Y;
            Storyboard.SetTarget(Yanimation, FlowtImagePopup);
            Storyboard.SetTargetProperty(Yanimation, new PropertyPath("VerticalOffset"));
            OpenAnimations.Children.Add(Yanimation);

            OpenAnimations.Begin();

        }

        //浮动图片框关闭动画
        private void FlowtImageCloseWithAnimation()
        {
            Storyboard CloseAnimations = new Storyboard();
            Duration duration = new Duration(TimeSpan.FromSeconds(0.3));

            DoubleAnimation OpacityAnimation = new DoubleAnimation();
            OpacityAnimation.Duration = duration;
            OpacityAnimation.To = 0;
            //OpacityAnimation.BeginTime = TimeSpan.FromSeconds(0.3);
            Storyboard.SetTarget(OpacityAnimation, FlowtImageBox);
            Storyboard.SetTargetProperty(OpacityAnimation, new PropertyPath("Opacity"));
            CloseAnimations.Children.Add(OpacityAnimation);

            CloseAnimations.Completed += (object sender, EventArgs e) =>
            {
                FlowtImagePopup.IsOpen = false;
            };
            CloseAnimations.Begin();
        }

        //回复框显示动画
        private void RGridOpenWithAnimation(Grid RGrid)
        {
            DoubleAnimation HeightAnimation = new DoubleAnimation();
            DoubleAnimation OpacityAnimation = new DoubleAnimation();

            Duration duration = new Duration(TimeSpan.FromSeconds(0.3));

            Storyboard.SetTarget(HeightAnimation, RGrid);
            Storyboard.SetTargetProperty(HeightAnimation, new PropertyPath("Height"));
            HeightAnimation.Duration = duration;
            HeightAnimation.To = 135;

            Storyboard.SetTarget(OpacityAnimation, RGrid);
            Storyboard.SetTargetProperty(OpacityAnimation, new PropertyPath("Opacity"));
            OpacityAnimation.Duration = duration;
            OpacityAnimation.To = 1;
            OpacityAnimation.BeginTime = TimeSpan.FromSeconds(0.3);

            Storyboard sb = new Storyboard();
            sb.Children.Add(HeightAnimation);
            sb.Children.Add(OpacityAnimation);

            RGrid.Visibility = System.Windows.Visibility.Visible;
            sb.Begin();
        }

        //回复框关闭动画
        private void RGridCloseWithAnimation(Grid RGrid)
        {
            DoubleAnimation HeightAnimation = new DoubleAnimation();
            DoubleAnimation OpacityAnimation = new DoubleAnimation();

            Duration duration = new Duration(TimeSpan.FromSeconds(0.3));

            Storyboard.SetTarget(HeightAnimation, RGrid);
            Storyboard.SetTargetProperty(HeightAnimation, new PropertyPath("Height"));
            HeightAnimation.Duration = duration;
            HeightAnimation.To = 0;
            HeightAnimation.BeginTime = TimeSpan.FromSeconds(0.3);

            Storyboard.SetTarget(OpacityAnimation, RGrid);
            Storyboard.SetTargetProperty(OpacityAnimation, new PropertyPath("Opacity"));
            OpacityAnimation.Duration = duration;
            OpacityAnimation.To = 0;
            
            Storyboard sb = new Storyboard();
            sb.Children.Add(HeightAnimation);
            sb.Children.Add(OpacityAnimation);

            sb.Completed += (object sender, EventArgs e) =>
            {
                RGrid.Visibility = System.Windows.Visibility.Collapsed;
            };
            sb.Begin();
        }

        

        #endregion

        #endregion

    }

    #region 值类型转换器

    public class ImageStringToImageSource : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Uri ImageUri = new Uri((String)value + "/40");
            
            //MessageBox.Show(value as String);
            return new BitmapImage(ImageUri);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class ImageToIsShowImage : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null || ((String)value).Length == 0) return Visibility.Collapsed;

            return Visibility.Visible;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class TweetTimeInfoToDate : IValueConverter
    {

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            MainPage.TweetTimeInfo timeInfo = (MainPage.TweetTimeInfo)value;
            DateTime now = DateTime.Now;
            Int64 DertaTime = timeInfo.SpreadTime - timeInfo.NowTime;

            DateTime SpreadTime = now.AddSeconds(DertaTime);

            return SpreadTime.ToString("MM-dd HH:mm");
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    #endregion

}